﻿using System;
using System.Collections.Generic;
using System.Linq;
using Abp.Domain.Uow;
using Hicap.AuthorizationServer.Core.Models.Sys;
using Microsoft.EntityFrameworkCore;

namespace Hicap.AuthorizationServer.EntityFrameworkCore.Seed.Host
{
    public class AuthObjectCreator
    {
        private readonly AuthorizationServerDbContext _context;
        private readonly string namespacePrefix = "Hicap.AuthorizationServer.Core.Models.";

        public AuthObjectCreator(AuthorizationServerDbContext context)
        {
            this._context = context;
        }

        private List<Type> GetDbContextGetGenericType()
        {
            var listtype = new List<Type>();
            var type = _context.GetType();

            var listpropertyies = type.GetProperties();

            foreach (var property in listpropertyies)
            {
                var t = property.PropertyType;
                if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(DbSet<>))
                {
                    var args = t.GetGenericArguments();
                    listtype.Add(args.First());
                }
            }

            return listtype;
        }

        private List<AuthObject> GetData()
        {
            var list = GetDbContextGetGenericType();
            var result = new List<AuthObject>();
            var root = new AuthObject()
            {
                ObjectCode = "Hicap.AuthorizationServer",
                ObjectName = "海普智联权限服务",
            };
            result.Add(root);

            var sys = new AuthObject()
            {
                ObjectCode = "Sys",
                ObjectName = "系统管理",
                ParentObject = root,
            };
            result.Add(sys);

            foreach (var type in list)
            {
                var data1 = new AuthObject();
                var data2 = new AuthObject();
                var data3 = new AuthObject();

                AuthObject parent = null;
                if (type.Namespace.Replace(namespacePrefix, string.Empty).Equals(sys.ObjectCode))
                {
                    parent = sys;
                }

                data1.ObjectCode = string.Join(".", parent.ObjectCode, type.Name);
                data1.ObjectName = string.Join(".", parent.ObjectName, type.Name);
                data1.ParentObject = parent;

                data2.ObjectCode = string.Join(".", data1.ObjectCode, "Upsert");
                data2.ObjectName = string.Join(".", data1.ObjectName, "新增或修改");
                data2.ParentObject = data1;

                data3.ObjectCode = string.Join(".", data1.ObjectCode, "Delete");
                data3.ObjectName = string.Join(".", data1.ObjectName, "删除");
                data3.ParentObject = data1;

                result.Add(data1);
                result.Add(data2);
                result.Add(data3);
            }

            return result;
        }

        public void Create(Role role)
        {
            CreateRole(role);
        }

        [UnitOfWork]
        private void CreateRole(Role role)
        {
            //AuthObject
            var authList = GetData();
            _context.AuthObject.AddRange(authList);
            _context.SaveChanges();

            authList.ForEach(x =>
            {
                _context.Attach(x);
                _context.AuthObjectRoleRelated.Add(new AuthObjectRoleRelated()
                {
                    AuthObject = x,
                    Role = role
                });
            });
            _context.SaveChanges();
        }
    }
}